Redis 数据类型
Redis 中的数据类型主要分为 字符串、哈希、列表、集合、有序集合、HyperLogLog、地理信息、Stream 等类型,字符串类型在上一章我们就已经介绍过,他通过 SET 就可以直接进行创建,而其他的数据类型则是需要通过其他的命令以及其下属配合的命令来完成操作。
哈希(Hash)
哈希是一个 string 类型的 字段(field) 以及值(value)映射表,可适用与存储对象,单个哈希键值可存储多大40亿字段值。
1 | 127.0.0.1:6379> HMSET hash_value name "kun" info "hello,world" url "http://jiangxue.org.cn" and "one" or "two" age "17" redis "redislabs.com" |
需要注意的是 Hashes 类型的字段依然是通过键值来进行存储的,如 name=kun、info=hello,world
可以通过使用 HMSET 来创建 hash 类型的键值对,也可以使用 HGETALL 来获取所有的字段值,当然也可以指定键名的方式来进行获取 HGETALL hash_value "name"。
| Id | Name | Info | Command |
|---|---|---|---|
| 1 | HMSET | 创建 hash 类型的键值段 | HMSET hash_value name "kun" info "hello,world" url "http://jiangxue.org.cn" |
| 2 | HMGET | 获取指定字段的值 | HMGET hash_value name |
| 2 | HGET | 获取存储在哈希表中指定的字段值 | HGET hash_value "name" |
| 3 | HSET | 自 redis 4.0 起可以一次性设置多个字段对,HMSET 区别是可以覆盖字段值 |
HSET hash_value age "10" |
| 4 | HSETNX | 为哈希表中不存在的字段赋值(如存在返回 0) | HSETNX hash_value about "jiangxue" |
| 5 | HGETALL | 获取全部或单个的 hash 类型键值段 | HGETALL hash_value or HGET hash_value "name" |
| 6 | HEXISTS | 查看哈希表中的 key 是否存在(存在返回 1,否则返回0) | HEXISTS hash_value "name" |
| 7 | HKEYS | 获取当前所有哈希表中的字段 | HKEYS hash_value |
| 8 | HVALS | 获取当前所有哈希表中的字段值 | HVALS hash_value |
| 9 | HLEN | 获取哈希表中字段的数量(从1开始) | HLEN hash_value |
| 10 | HDEL | 删除一个多多个哈希表中的键值对 | HDEL hash_value "and" "or" |
| 11 | HINCRBY | 为指定的哈希表中的 key 增加或减少数值(整数) | HINCRBY hash_value age 1 (原本 17将会被增加1,得出 18) |
| 12 | HINCRBYFLOAT | 与 HINCRBY 的区别是支持非整数计算以及科学计数法 |
HINCRBYFLOAT hash_value age -1.5 (18-1.5 得出 16.5) |
| 13 | HSCAN | 模糊搜索哈希表中的字段,并返回键值段 | HSCAN hash_value 0 match "na*" (返回 name 字段即值) |
| 14 | HSTRLEN | 返回字段值的长度 | HSTRLEN hash_value "name" |
列表(List)
列表在 Redis 中表示可以将数据按顺序排序插入的字符串列表,通常可以包含超过40亿个元素,这启动主要通过 LPUSH 来插入一个或多个到列表头部,以及通过 LRANGE 来获取列表范围
1 | 127.0.0.1:6379> LPUSH list_key redis |
| Id | Name | Info | Command |
|---|---|---|---|
| 1 | LPUSH | 将一个或多个值插入到列表头部 (如果 key 不存在则会创建一个) | LPUSH list_key mongoDB |
| 2 | RPUSH | 将一个或多个值插入到表尾部(如果 key 不存在则会创建一个) | RPUSH list_key "nice!" |
| 3 | LPUSHX | key 不存在时不进行任何操作并返回 0,存在的话则将值插入到列表头部 | LPUSHX list_key "hello" |
| 4 | RPUSHX | key 不存在时不进行任何操作并返回 0,存在的话则将值插入到列表尾部 | RPUSHX list_keys "world" |
| 5 | LINSERT | 在指定元素前插入列表数据 | LINSERT list_key BEFORE "redis" "redislab.com" (在 redis 前插入 redislab.com) |
| 6 | LSET | 通过索引替换列表元素(以0开始) | LSET list_key 0 "start"(将 索引为0的元素替换为 “start”) |
| 7 | LRANGE | 在一定范围内获取列表内元素 | LRANGE list_key 0 100 |
| 8 | LINDEX | 返回指定索引对应的表内元素(超出范围返回 nill) | LINDEX list_key 0 |
| 9 | BRPOPLPUSH | 将指定列表内最后一个元素插入到另外一个列表的头部(如果列表没有元素会阻塞到超时为止,或者发现可以移出的元素为止,单位是秒,需要注意的是如果超时参数是 0 ,那么将会表示阻塞的时间可以无限期延长) | BRPOPLPUSH list_key key_name 500 |
| 10 | LLEN | 获取列表的元素数量 | LLEN list_key |
| 11 | LTRIM | 用于修建已经存在列表内的元素(要么从前删除要么从后删除,不可跨越索引) | LTRIM list_key -1 -1 (从倒数地一个开始,然后直到倒数第一个,也就是说之保留倒数地一个) |
| 12 | BLPOP | 移出第一个列表元素,并返回所移出的列表名称和元素 | BLPOP list_key 0 |
| 13 | BRPOP | 移出列表最后一个元素,同样返回岁移出的列表名和元素 | LRANGE list_key 0 -1 |
| 14 | LPOP | 移出列表中地一个元素(与 BLPOP 的区别是不用设置阻塞时间) | LPOP list_key 1 |
| 15 | LREM | 指定一个或多个列表中相同元素进行删除 | LREM list_key 1 "sql" |
LTRIM

在 Redis 中 LTRIM 主要用于修剪(删除)已经存在的列表内的元素,其中分为 start 以及 stop 以 0 为开始,-1 可以表示列表里面的最后一个元素,-2 表倒数第二个 ……(这适用绝大多数依赖索引所完成的命令,如 RANGE)
1 | 127.0.0.1:6379> LRANGE list_key 0 1000 |
要么从前删除要么从后删除,不可跨越索引
我们所构造的 -1~-1 翻译到人可以理解的那就是,从倒数地一个开始,然后直到倒数第一个,也就是说之保留倒数地一个,当然你也可以通过 LTRIM list_key -6 -1 从倒数第六到最后一个来进行保留,删除其余外的元素:
1 | 127.0.0.1:6379> LTRIM list_key -6 -1 |
BLPOP
主要的作用就是移出指定列表中的第一个元素,并返回所移出的元素名称,如果列表没有元素或没有该列表,则会等待超时时间过后即可关闭阻塞,或者得到发现可以移出的元素为止。
1 | 127.0.0.1:6379> LRANGE list_key 0 -1 |
LTRIM

LTRIM 与列表中所有的移出命令不同的是,他可以指定一个或多个在列表中相同的元素进行删除。
1 | 127.0.0.1:6379> LPUSH list_key "sql" sql sql |
集合(Set)
集合(set)是一个字符串类型的无序集合,集合成员是唯一的,因此这意味着在集合中不可以有重复的成员数据,每个集合中最大可以存储40多亿个成员数据。通常可以通过 SADD 创建一个集合并向其添加成员(一个或多个),之后 SMEMBERS 来返回集合中的所有成员。
1 | 127.0.0.1:6379> SADD set_key sql mysql redis mongoDB |
| Id | Name | Info | Command |
|---|---|---|---|
| 1 | SADD | 创建集合并向其中添加一个或多个成员 | SADD set_key sql mysql redis mongoDB |
| 2 | SINTERSTORE | 将两个集合中相同的成员保存在另一个集合中 | SINTERSTORE set_key set_one set_two |
| 3 | SDIFFSTORE | 将两个集合中不相同的成员数据保存到另一个集合中 | SDIFFSTORE set_key set_one set_two (将 set_one 和 set_two 两个集合之间不相同的成员保存到 set_key 集合中) |
| 4 | SUNIONSTORE | 将两个或多个集合之间的成员进行合并到另一个集合中 | SUNIONSTORE key_set set_one set_two |
| 5 | SMOVE | 将一个集合中的成员移动到另一个集合中 | SMOVE set_one set_two "sql" (将 set_one 集合中的成员“sql” 移动到 set_two 中) |
| 6 | SDIFF | 返回指定集合中的不同成员 | SDIFF set_two set_one |
| 7 | SINTER | 返回指定集合中相同的成员 | SINTER set_one set_two |
| 8 | SUNION | 返回将指定集合合并后的并集 | SUNION set_one set_two |
| 9 | SMEMBERS | 返回指定集合中所有的成员 | SMEMBERS set_key |
| 10 | SISMEMBER | 判断集合中成员是否存在(存在返回1,不存在返回0) | SISMEMBER set_one "mysql" |
| 11 | SSCAN | 遍历指定集合中所存在的键元素 | SSCAN set_two 0 MATCH s* (匹配该集合中所有以 “s” 开头的成员 ) |
| 12 | SRANDMEMBER | 随机返回指定集合中的成员数(如果数大于成员数那么将返回所有成员) | SRANDMEMBER set_two 10 |
| 13 | SPOP | 根据指定数值随机删除集合成员,并返回所删除的成员数据 | SPOP set_two 3 |
| 14 | SREM | 删除一个或多个集合中的成员 | SREM set_two "mysql" |
SINTERSTORE

SINTERSTORE 命令在 Redis 中的主要作用就是将两个集合中相同的成员数据添加到另一个集合中。
1 | 127.0.0.1:6379> SMEMBERS set_one |
SDIFF

返回两个集合中不相同的成员数据,相同的数据将不会被输出,按照官方的意思说这个命令主要返回地一个集合与其他集合之间的差异(说人话就是将其他集合不相同的数据进行输出)
1 | 127.0.0.1:6379> SDIFF set_two set_one |
在集合中有两个非常重要的名词,分别是交集和差集,交集就是相同的意思,而差集就不相同的意思。
SDIFFSTORE
SDIFFSTORE 与 SDIFF 类似,但他主要的作用就是将两个集合之间的不相同数据(也就是差值)保存到另一个集合之中
1 | 127.0.0.1:6379> SDIFFSTORE set_key set_one set_two |
SINTER

SINTER 与 SDIFF 不同之处在于,SINTER 用于返回所有集合中的交集,也就是相同的成员集合。
1 | 127.0.0.1:6379> SINTER set_one set_two |
SINTERSTORE
Redis 是一个考虑很全面的 key-value 数据库,因此他的命令也非常的具有针对性,该命令与 SDIFF 中的 SDIFFSTORE 非常相似,但该命令是将两个集合中的交集存储到另一个集合中:
1 | 127.0.0.1:6379> SINTERSTORE set_key set_one set_two |
SUNION

SUNION 简单来说就是将两个集合并集,也就是将两个集合合并,将相同的数据所剔除,与 SDIFF 和 SINTER 一样,分为输出和存储两个非常具有针对性的命令。
1 | 127.0.0.1:6379> SUNION set_one set_two |
所谓“并集” 也就是将两个或多个集合成员进行合并,如果不同集合之间的成员数据相同将会被剔除。
SUNIONSTORE
SUNIONSTORE 同样集成了 SUNION 命令逻辑,只不过是将输出改为了存储,将两个或多个集合之间的成员进行并集
1 | 127.0.0.1:6379> SUNIONSTORE key_set set_one set_two |
有序集合(Zset)
有序集合(zset)和集合同样都是一个字符串类型的集合元素,他们都不允许同样重复的成员。不同的是他拥有一个双精度浮点数来达到从达到小排序的效果,与集合一样可以存储越 40亿个成员。
作为 Redis 几个最为主要的数据类型,他同样拥有针对性的命令,分别为 ZADD 即添加有序集合,他可以添加多个或单个(取决与你的习惯),当然也有 ZRANGE 来进行输出。
1 | 127.0.0.1:6379> ZADD key_zset 1 sql 2 mysql 3 mongoDB 4 redis |
ZRANGE(从小到大)

ZRANGE 命令会按照数值从小到大来进行排序(具有相同数值的成员将会被按照字典序列来进行排序)
字典序列也就是根据 A、B、C、D 这个序列来进行从小到大来进行划分,也就是根据首字母开头进行排序。
在通过 ZRANGE 命令进行查询的时候,如果不加上 WITHSCORES 返回的是一个元素列表,加上的话返回的则是一个数组列表。
1 | 127.0.0.1:6379> ZRANGE key_zset 0 -1 |
ZRANGEBYLEX
当集合中的元素都以相同的方式进行插入时,那么将会强制按照字典顺序来进行排列(在 Redis 中默认为英文字典 ABC以此类推进行排序)。
在这个命令中他支持有效的 start 以及 stop 修饰符,分别为 [ 以及 ) 和 - \ + 等。其中 -/+ 分别表示最小和最大字符串,也就是开始和结尾,而 [/( 的区别是输出时是否包含元素 [ 是包含 ( 即不包含。
1 | 127.0.0.1:6379> ZRANGEBYLEX key_zset - + |
ZRANGEBYSCORE
ZRANGEBYSCORE 与 ZRANGEBYLEX 相似,但以我个人感觉更喜欢后者,前者的 -inf 和 +inf 与后者的 -/+ 功能基本一样,区别是多了个 ”inf“,而之后的 [ 和 ( 功能也很一样,但将需要通过元素来作为参数改为了数值(在ZRANGEBYSCORE 中 [ 并不支持)。
1 | 127.0.0.1:6379> ZRANGEBYSCORE key_zset 1 2 |
ZSCORE
ZSCORE 命令是上述几个查询命令中最为朴素的命令之一,他主要根据成员名称来返回在其集合中的索引号
1 | 127.0.0.1:6379> ZRANGE zset_one 0 -1 WITHSCORES |
ZCOUNT
ZCOUNT 同样支持 ( 以及 -inf\+inf这类的表达式,他主要的作用就是计算出集合中的成员数。
1 | 127.0.0.1:6379> ZRANGE zset_two 0 -1 |
ZREVRANK(从大到小)
ZREVRANK 同样是从大到小根据 0 为起始点进行排序,与 ZREVEANGE 类似,但该命令主要通过成员来返回在其集合中的索引。
1 | 127.0.0.1:6379> ZRANGE zset_one 0 -1 |
ZREVRANGEBYSCORE
ZREVRANGEBYSCORE 可以理解为是 ZREVRANK 的延续之作,他除了索引之外还支持 ZRANGEBYLEX 其中的表达式,除此之外还整合了 ZRANGEBYSCORE 来打通信息屏障,通过差异化和颗粒度达到引爆点来聚焦用户感知赛道。
1 | 127.0.0.1:6379> ZREVRANGEBYSCORE zset_one 4 1 |
ZREVEANGE
ZREVRANGE 是一个更加纯粹的返回字典序列的一个命令,他比 ZRANGE 这群命令显得更加的纯粹和干练,同样是返回集合的作用,该命令只需要指定索引即可,不支持任何华丽胡少的表达式(但支持 redis 自带的)
1 | 127.0.0.1:6379> ZREVRANGE zset_one 0 -1 |
ZINCRBY
ZINCRBY 简单来讲就是对集合元素中的数组进行增加,假设集合中元素的数组为 0,那么即可通过 ZINCRBY 来进行增加:
1 | 127.0.0.1:6379> ZINCRBY key_zset 10 "three" |
并集/合集
ZINTERSTORE(合集)
将两个集合之间的交集存储到另一个集合中,需要指定两个集合中相同数的数值(也就是最终相同数所存储到另一个集合中的数量),默认情况下,结果集中的元素数值是这些集合中元素数值之和。
1 | 127.0.0.1:6379> ZINTERSTORE zset_key 2 zset_one zset_two |
ZUNIONSTORE (并集)
ZUNIONSTORE 与 ZINTERSTORE 的区别就是一个是合集另一个是并集的一字之差,说简单一点就是将两个集合进行合并,相同的元素剔除。
1 | 127.0.0.1:6379> ZRANGE zset_two 0 -1 |
但这样会造成集合中索引的相同,为了避免这类事情的发生我们可以自定义权重或和来解决 ZUNIONSTORE zset_key 2 zset_one zest_two WEIGHTS 2 3 [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX],这同样在 ZINTERSTORE 命令中适用。
ZRANK
ZRANK 简单来说就单纯的是一个可以根据其集合成员来返回其索引的作用,如果其成员不存在则会返回 nil
1 | 127.0.0.1:6379> ZRANK zset_one "day" |
ZREM
ZREM 没有像后续几条命令一样那么否有诗书气自华,他主要根据成员来针对单个集合进行删除,在 Redis => 2.4 版本中支持删除多个成员。
1 | 127.0.0.1:6379> ZADD key_zset 0 day 1 one 2 two 3 three 3 four |
ZREMRANGEBYLEX
该命令与 ZREM 相比起来就非常的丰富,他支持了一些较为简单的 Redis 表达式([ 包括自己),适合多个成员一起删除,当然你也可以选择删除单个(弊端就是你删除不了第一个和倒数第二个成员)。
但是 ZREMRANGEBYLEX 的弊端就是需要该集合索引都是一样的才可以进行删除。
1 | 127.0.0.1:6379> ZRANGE key_zset 0 -1 WITHSCORES |
ZREMRANGEBYRANK
该命令同样非产简约优雅,通过 start\stop 的操作可以快速删除多个集合中的成员,但劣势也一样展现出来,他并不能删除单个成员。
1 | 127.0.0.1:6379> ZRANGE key_zset 0 -1 WITHSCORES |
ZREMRANGEBYSCORE
到 ZREMRANGEBYSCORE Reids 的有序列表删除命令就发展的非常特别且简单优雅,他同样适合于多个成员的删除操作,与前者不同的是到他这开始支持了 -inf 和 ( (不包含该成员) 这类的表达式。
1 | 127.0.0.1:6379> ZRANGE key_zset 0 -1 WITHSCORES |
